package c.x.jy.admin.controller;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import c.x.jy.admin.oauth2.OAuth2Token;
import c.x.jy.common.annotation.SysLog;
import c.x.jy.common.utils.Constant;
import c.x.jy.common.utils.CookieUtil;
import c.x.jy.common.utils.R;
import c.x.jy.common.utils.SysUtils;
import c.x.jy.dao.entity.SysRoleEntity;
import c.x.jy.dao.entity.SysUserEntity;
import c.x.jy.service.entity.form.LoginForm;
import c.x.jy.service.redis.Cache;
import c.x.jy.service.service.CaptchaService;
import c.x.jy.service.service.ShiroService;
import c.x.jy.service.service.SysRoleService;
import c.x.jy.service.service.SysUserService;
 
@RestController
public class LoginController extends AbstractController {

	public static final int EXPIRE = 3600;

	@Autowired
	private SysUserService sysUserService;
	 @Autowired
    private SysRoleService sysRoleService;
	@Autowired
	private CaptchaService captchaService;
	@Autowired
	private Cache redisUtils;
	@Autowired
	private ShiroService shiroService;

	/**
	 * 验证码
	 */
 
	@GetMapping("captcha.jpg")
	public void captcha(HttpServletResponse response, String uuid) throws IOException {
		response.setHeader("Cache-Control", "no-store, no-cache");
		response.setContentType("image/jpeg");

		// 获取图片验证码
		BufferedImage image = captchaService.getCaptcha(uuid);

		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(image, "jpg", out);
		IOUtils.closeQuietly(out);
	}

	/**
	 * 登录
	 */
	//   @SysLog("用户登陆")
	@PostMapping("/sys/login")
	@ResponseBody
	public Map<String, Object> login(@RequestBody LoginForm form,HttpServletRequest request ,	  HttpServletResponse httpResponse) {
		 
		   boolean captcha = captchaService.validate(form.getUuid(), form.getValidCode());
		   if(!captcha){ return R.error("验证码不正确"); }
	 
	
		// 用户信息
		SysUserEntity user = sysUserService.queryByUserName(form.getUsername());
	 
		// 账号不存在、密码错误
		if (user == null
				|| !user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
			return R.error("账号或密码不正确");
		}

		// 账号锁定
		if (user.getStatus() == 0) {
			return R.error("账号已被锁定,请联系管理员");
		}


	 	List<SysRoleEntity>	roles=	sysRoleService.selectRolesByUserId(user);
		 Set<String>  setlist=shiroService.getUserPermissions(user.getUserId());
		 user.setPermissions(setlist);
		 user.setRoles(roles);
		// 生成一个token
		String token =SysUtils.generateCode();// 	request.getRequestedSessionId();
		user.setToken(token);
		user.setPassword(null);
	    user.setSalt(null); 

    
	      
	    
	    //如果已经登陆退出旧用户  一个帐号只能登陆一次
//		Set<String> keys=	redisUtils.keys(Constant.USERKEY+user.getUserId()+":*");
	//	 if(keys!=null)keys.forEach(k->{ if(k!=null)redisUtils.remove( redisUtils.get(k));  }  );
		 
		redisUtils.set(token, user, Long.valueOf(EXPIRE));
		redisUtils.set(Constant.USERKEY+user.getUserId()+":"+token, token, Long.valueOf(EXPIRE));
		 
			SecurityUtils.getSubject().login(new OAuth2Token(token ));
		 
		CookieUtil.doSetCookie(request, httpResponse, "token", token, EXPIRE*10, true);
		// redisUtils.set("login_"+user.getUserId() , token, EXPIRE);

		return R.ok().put("token", token).put("expire", EXPIRE);

	}

	public static void main(String[] args) {
		String pwd = "1111";
		String salt = "1e9c36676baf846bcbf6d6bbeec3fc24";
		System.out.println(new Sha256Hash(pwd, salt).toHex());
	}

	/**
	 * 退出
	 */
	//  @SysLog("用户退出")
	@RequestMapping("/sys/logout")
	public String logout() {
			SysUserEntity u =(SysUserEntity) SecurityUtils.getSubject().getPrincipal();
			//退出所有用户
		redisUtils.remove(Constant.USERKEY+u.getUserId()+":"+u.getToken());
		redisUtils.remove(u.getToken());
	
		 
		SecurityUtils.getSubject().logout();
		return "forward:/login.html";
	}
	
	/**
	 * 重置密码
	 * @param userId
	 * @return
	 */
	   @SysLog("重置用户密码")
	@RequestMapping(value="/sys/{userId}/password",method = RequestMethod.PUT)
	@ResponseBody
	public Map<String, Object> password(@PathVariable("userId") Long userId) {
		   
		    SysUserEntity user = sysUserService.getById(userId);
		if(user.getBusinessId().equals(Constant.SUPER_ADMIN)) {
        	return	R.error("超级管理员不充许更改");
        		
        	}
		sysUserService.restPassword(userId);
		Set<String> keys=	redisUtils.keys(Constant.USERKEY+userId+":*");
		 if(keys!=null)keys.forEach(k->{ if(k!=null)redisUtils.remove( redisUtils.get(k));  }  );
    	 
		return R.ok();
	}

}
